package com.wjw.java.collection.set_;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * HashSet练习:
 * 定义一个User类,属性有name,age
 * 创建3个User对象,放入Hashset中
 * 当name和age的值相同时,认为是相同员工,不能放入Hashset中
 */
public class Exercise_HashSet {
    public static void main(String[] args) {
        Set<String> set1 = new HashSet<>();
        set1.add("wjw");
        set1.add("wjw");
        set1.add("dw");
        System.out.println(set1);

        //对象需重写Hashcode和equals方法去重
        //快捷键:右键 -> Generate -> equals() and hashcode() -> java7+
        Set<User> set2 =  new HashSet<>();
        User u1 = new User("wjw",18);
        User u2 = new User("wjw",18);
        User u3 = new User("dw",18);
        /**
         * 第一次add()：计算hash值(table的索引值),找到存储数据表table,看这个索引位置是否已经存在元素
         * 没有元素,直接加入
         *
         * 第二次add()：计算hash值(table的索引值),找到存储数据表table,看这个索引位置是否已经存在元素
         * 没有元素,直接加入
         *
         * 第三次add()：计算hash值(table的索引值),找到存储数据表table,看这个索引位置是否已经存在元素
         * 有元素,因为重写了hashcode方法,和第一次添加的hashcode值相同,
         * 则调用equal方法比较,如果相同就放弃添加,如果不同,则添加到最后
         */
        set2.add(u1);//成功
        set2.add(u2);//成功
        set2.add(u3);//失败
        System.out.println(set2);
    }
}

class User{
    private String name;
    private Integer age;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return this.age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public User() {}

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 根据name和age计算hashCode
     * 如果name和age值相等,则hashCode相等
     * @return
     */
    @Override
    public int hashCode() {
        return Objects.hash(this.name, this.age);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || this.getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(this.name, user.name) &&
                Objects.equals(this.age, user.age);
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
